package com.shared_file_bucket.controller;


import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.shared_file_bucket.common.constant.CommonConstant;
import com.shared_file_bucket.common.domain.R;
import com.shared_file_bucket.common.utils.ZipUtils;
import com.shared_file_bucket.model.FileAddDTO;
import com.shared_file_bucket.model.ShareDir;
import com.shared_file_bucket.service.LocalFileService;
import com.shared_file_bucket.service.ShareDirService;
import com.shared_file_bucket.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.util.List;
import java.util.UUID;

@RestController
@RequestMapping("shareDir")
@RequiredArgsConstructor
public class ShareDirController {

    private final ShareDirService shareDirService;

    private final LocalFileService localFileService;

    private final UserService userService;

    @Value("${server.port}")
    private String port;

    /**
     * 获取文件列表
     *
     * @return
     */
    @GetMapping({"/list"})
    public R getList() {
        LambdaQueryWrapper<ShareDir> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ShareDir::getUserId, StpUtil.getLoginIdAsLong());
        List<ShareDir> list = shareDirService.list(wrapper);
        return R.succeed(list, "查询成功");
    }

    @PostMapping({"/create"})
    public R create(String dirName) throws IOException {

        // 创建文件夹
        FileAddDTO fileAddDTO = new FileAddDTO();
        fileAddDTO.setDir("/");
        fileAddDTO.setIsDirectory(true);
        fileAddDTO.setFileName(dirName);
        localFileService.addFile(localFileService.getRootByUserId(), fileAddDTO);

        ShareDir shareDir = new ShareDir();
        shareDir.setDirName(dirName);
        InetAddress inetAddress = InetAddress.getLocalHost();
        String ipAddress = inetAddress.getHostAddress();
        shareDir.setIp(ipAddress + ":" + port);
        shareDir.setUserId(StpUtil.getLoginIdAsLong());
        shareDir.setUuid(UUID.randomUUID().toString().replaceAll("-", ""));
        shareDirService.save(shareDir);

        return R.succeed("创建成功");
    }

    @PostMapping({"/remove"})
    public R remove(String id) throws IOException {

        ShareDir shareDir = shareDirService.getById(id);
        String[] filePathArr = new String[]{
                shareDir.getDirName()
        };
        localFileService.deleteFiles(localFileService.getRootByUserId(), filePathArr);

        shareDirService.removeById(id);
        return R.succeed("删除成功");
    }

    /**
     * 重命名文件
     *
     * @return
     * @throws IOException
     */
    @PostMapping("/modifyRoot")
    public R<?> modifyRoot(String root) throws IOException {
        userService.modifyRoot(root);
        return R.succeed("修改成功");
    }

    /**
     * 打包
     *
     * @return
     * @throws IOException
     */
    @PostMapping("/package")
    public void packageDir(HttpServletResponse response, String folderPath) {

        String sourceDirPath = localFileService.getRootByUserId() + CommonConstant.DIR_SPLIT + folderPath;
        String zipFileName = UUID.randomUUID() + ".zip";
        String zipFilePath = localFileService.getRootByUserId() + CommonConstant.DIR_SPLIT + zipFileName;

        try {
            ZipUtils.zipDirectory(sourceDirPath, zipFilePath);
            sendFileAsResponse(zipFileName, zipFilePath, response);
        } catch (IOException e) {
            e.printStackTrace();
            response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
        }
    }

    private void sendFileAsResponse(String fileName, String filePath, HttpServletResponse response) throws IOException {
        response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");

        try (FileInputStream fis = new FileInputStream(filePath); OutputStream os = response.getOutputStream()) {
            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = fis.read(buffer)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
        } catch (IOException e) {
            throw new IOException("Error occurred while sending file as response", e);
        }
    }
}

